#include "ecap_driver.h"

ecap_data_T	ecap_data[3]={
		{A_RTD,},
		{B_RTD,},
		{PHASE,},
};

void USER_ConfigEcap(uint32_t ecapBase);
void USER_InitECAP(void)
{
    Interrupt_register(INT_ECAP1, &ecap1ISR);
    Interrupt_register(INT_ECAP2, &ecap2ISR);
    Interrupt_register(INT_ECAP3, &ecap3ISR);
    //
    // Disable ,clear all capture flags and interrupts
    //
    USER_ConfigEcap(ECAP1_BASE);
    USER_ConfigEcap(ECAP2_BASE);
    USER_ConfigEcap(ECAP3_BASE);


    Interrupt_enable(INT_ECAP1);
    Interrupt_enable(INT_ECAP2);
    Interrupt_enable(INT_ECAP3);
}

void USER_ConfigEcap(uint32_t ecapBase)
{
    ECAP_disableInterrupt(ecapBase,
                          (ECAP_ISR_SOURCE_CAPTURE_EVENT_1  |
                           ECAP_ISR_SOURCE_CAPTURE_EVENT_2  |
                           ECAP_ISR_SOURCE_CAPTURE_EVENT_3  |
                           ECAP_ISR_SOURCE_CAPTURE_EVENT_4  |
                           ECAP_ISR_SOURCE_COUNTER_OVERFLOW	|
                           ECAP_ISR_SOURCE_COUNTER_PERIOD   |
                           ECAP_ISR_SOURCE_COUNTER_COMPARE
						   ));
    ECAP_clearInterrupt(ecapBase,
                        (ECAP_ISR_SOURCE_CAPTURE_EVENT_1  |
                         ECAP_ISR_SOURCE_CAPTURE_EVENT_2  |
                         ECAP_ISR_SOURCE_CAPTURE_EVENT_3  |
                         ECAP_ISR_SOURCE_CAPTURE_EVENT_4  |
                         ECAP_ISR_SOURCE_COUNTER_OVERFLOW	|
                         ECAP_ISR_SOURCE_COUNTER_PERIOD   |
                         ECAP_ISR_SOURCE_COUNTER_COMPARE
						 ));

    //
    // Disable CAP1-CAP4 register loads
    //
    ECAP_disableTimeStampCapture(ecapBase);

    //
    // Configure eCAP
    //    Enable capture mode.
    //    One shot mode, stop capture at event 4.
    //    Set polarity of the events to rising, falling, rising, falling edge.
    //    Set capture in time difference mode.
    //    Select input from XBAR7.
    //    Enable eCAP module.
    //    Enable interrupt.
    //
    ECAP_stopCounter(ecapBase);
    ECAP_enableCaptureMode(ecapBase);

    ECAP_setCaptureMode(ecapBase, ECAP_ONE_SHOT_CAPTURE_MODE, ECAP_EVENT_4);

    ECAP_setEventPolarity(ecapBase, ECAP_EVENT_1, ECAP_EVNT_RISING_EDGE);
    ECAP_setEventPolarity(ecapBase, ECAP_EVENT_2, ECAP_EVNT_FALLING_EDGE);
    ECAP_setEventPolarity(ecapBase, ECAP_EVENT_3, ECAP_EVNT_RISING_EDGE);
    ECAP_setEventPolarity(ecapBase, ECAP_EVENT_4, ECAP_EVNT_FALLING_EDGE);

    ECAP_enableCounterResetOnEvent(ecapBase, ECAP_EVENT_1);
    ECAP_enableCounterResetOnEvent(ecapBase, ECAP_EVENT_2);
    ECAP_enableCounterResetOnEvent(ecapBase, ECAP_EVENT_3);
    ECAP_enableCounterResetOnEvent(ecapBase, ECAP_EVENT_4);

    ECAP_enableLoadCounter(ecapBase);
//    ECAP_setSyncOutMode(ECAP1_BASE, ECAP_SYNC_OUT_COUNTER_PRD);
    ECAP_startCounter(ecapBase);
    ECAP_enableTimeStampCapture(ecapBase);
    ECAP_reArm(ecapBase);

    ECAP_enableInterrupt(ecapBase, ECAP_ISR_SOURCE_CAPTURE_EVENT_4);
}


float get_ecapDutyCycle(ECAPPin_E Pin_Name)
{
    if(Pin_Name>3)
    {
    	return 0;
    }
	return ecap_data[Pin_Name].ecap_dutyCycle;
}

uint16_t get_ecapDutyCycleFix(ECAPPin_E Pin_Name)
{
    return (uint16_t)(get_ecapDutyCycle(Pin_Name)*10000);
}

int16_t get_ecapCycleTime(ECAPPin_E Pin_Name)
{
    if(Pin_Name>2)
    {
        return 0;
    }
    return ecap_data[Pin_Name].ecap_cycleTime;
}

__interrupt void ecap1ISR(void)
{

    //
    // Get the capture counts. Each capture should be 4x the ePWM count
    // because of the ePWM clock dividers.
    //
	ecap_data[0].ecap_startTime=ECAP_getTimeBaseCounter(ECAP1_BASE);
	ecap_data[0].ecap_highLevelTime = ECAP_getEventTimeStamp(ECAP1_BASE, ECAP_EVENT_2);
	ecap_data[0].ecap_lowLevelTime = ECAP_getEventTimeStamp(ECAP1_BASE, ECAP_EVENT_3);
//	ecap_data.ecap_endTime=ECAP_getTimeBaseCounter(ECAP1_BASE, ECAP_EVENT_4);
	ecap_data[0].ecap_cycleTime=ecap_data[0].ecap_highLevelTime+ecap_data[0].ecap_lowLevelTime;
	ecap_data[0].ecap_dutyCycle=(float)ecap_data[0].ecap_highLevelTime/(ecap_data[0].ecap_highLevelTime+ecap_data[0].ecap_lowLevelTime);
//	ecap_data.ecap_dutyCycle=ecap_data.ecap_highLevelTime/(ecap_data.ecap_highLevelTime+ecap_data.ecap_lowLevelTime);

    ECAP_clearInterrupt(ECAP1_BASE,ECAP_ISR_SOURCE_CAPTURE_EVENT_4);
    ECAP_clearGlobalInterrupt(ECAP1_BASE);
//
//    //
//    // Start eCAP
//    //
    ECAP_reArm(ECAP1_BASE);
//
//    //
//    // Acknowledge the group interrupt for more interrupts.
//    //
    Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP4);
}

__interrupt void ecap2ISR(void)
{

    //
    // Get the capture counts. Each capture should be 4x the ePWM count
    // because of the ePWM clock dividers.
    //
	ecap_data[1].ecap_startTime=ECAP_getTimeBaseCounter(ECAP2_BASE);
	ecap_data[1].ecap_highLevelTime = ECAP_getEventTimeStamp(ECAP2_BASE, ECAP_EVENT_2);
	ecap_data[1].ecap_lowLevelTime = ECAP_getEventTimeStamp(ECAP2_BASE, ECAP_EVENT_3);
//	ecap_data.ecap_endTime=ECAP_getTimeBaseCounter(ECAP1_BASE, ECAP_EVENT_4);
	ecap_data[1].ecap_cycleTime=ecap_data[1].ecap_highLevelTime+ecap_data[1].ecap_lowLevelTime;
	ecap_data[1].ecap_dutyCycle=(float)ecap_data[1].ecap_highLevelTime/(ecap_data[1].ecap_highLevelTime+ecap_data[1].ecap_lowLevelTime);
//	ecap_data.ecap_dutyCycle=ecap_data.ecap_highLevelTime/(ecap_data.ecap_highLevelTime+ecap_data.ecap_lowLevelTime);

    ECAP_clearInterrupt(ECAP2_BASE,ECAP_ISR_SOURCE_CAPTURE_EVENT_4);
    ECAP_clearGlobalInterrupt(ECAP2_BASE);
//
//    //
//    // Start eCAP
//    //
    ECAP_reArm(ECAP2_BASE);
//
//    //
//    // Acknowledge the group interrupt for more interrupts.
//    //
    Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP4);
}

__interrupt void ecap3ISR(void)
{

    //
    // Get the capture counts. Each capture should be 4x the ePWM count
    // because of the ePWM clock dividers.
    //
	ecap_data[2].ecap_startTime=ECAP_getTimeBaseCounter(ECAP3_BASE);
	ecap_data[2].ecap_highLevelTime = ECAP_getEventTimeStamp(ECAP3_BASE, ECAP_EVENT_2);
	ecap_data[2].ecap_lowLevelTime = ECAP_getEventTimeStamp(ECAP3_BASE, ECAP_EVENT_3);
//	ecap_data.ecap_endTime=ECAP_getTimeBaseCounter(ECAP1_BASE, ECAP_EVENT_4);
	ecap_data[2].ecap_cycleTime=ecap_data[2].ecap_highLevelTime+ecap_data[2].ecap_lowLevelTime;
	ecap_data[2].ecap_dutyCycle=(float)ecap_data[2].ecap_highLevelTime/(ecap_data[2].ecap_highLevelTime+ecap_data[2].ecap_lowLevelTime);
//	ecap_data.ecap_dutyCycle=ecap_data.ecap_highLevelTime/(ecap_data.ecap_highLevelTime+ecap_data.ecap_lowLevelTime);

    ECAP_clearInterrupt(ECAP3_BASE,ECAP_ISR_SOURCE_CAPTURE_EVENT_4);
    ECAP_clearGlobalInterrupt(ECAP3_BASE);
//
//    //
//    // Start eCAP
//    //
    ECAP_reArm(ECAP3_BASE);
//
//    //
//    // Acknowledge the group interrupt for more interrupts.
//    //
    Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP4);
}

void startAllEcap(void)
{
    ECAP_startCounter(ECAP1_BASE);
    ECAP_startCounter(ECAP2_BASE);
    ECAP_startCounter(ECAP3_BASE);
}

void stopAllEcap(void)
{
    ECAP_stopCounter(ECAP1_BASE);
    ECAP_stopCounter(ECAP2_BASE);
    ECAP_stopCounter(ECAP3_BASE);
}
